package manager.connection;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.http.client.utils.URIBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import advice.ExceptionManager;
import alisms.SmsDemo;
import database.DBService;
import database.pojo.UserInfo;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import manager.connection.state.MachineStatus;
import manager.connection.type.ConnectionInfo;
import manager.connection.type.MachineActivateInfo;
import manager.http.HttpClient;
import manager.pay.GetPayResult;
import manager.pay.type.EndTimeInfo;
import manager.player.PlayerManager;
import manager.qrcode.QRCodeManager;
import net.socket.server.SocketServer;
import net.socket.server.message.MessageManager;
import net.socket.server.notification.GameServerWechatLoginNTF;
import net.socket.server.notification.MachineIDLeavedNTF;
import net.socket.server.notification.MachineIdStatusNTF;
import net.socket.server.protocal.PROTOID;
import net.socket.server.request.IRequest;
import net.socket.server.request.MachineLoginRequest;
import net.socket.server.request.MachineTimeVerificationRequest;
import net.socket.server.request.PlayerLogoutRequest;
import net.socket.server.response.MachineLoginResponse;
import net.socket.server.response.MachineTimeVerificationResponse;
import net.socket.server.response.PlayerLogoutResponse;
import observable.subject.MessageCenter;
import service.IUserLogin;
import service.message.QRCodeEvent;
import service.message.WeixinUserInfo;
import util.MyFactory;
import util.ResultTypeList;
import net.socket.server.request.testLogin;
@Component("ClientConnectionManager")
public class ClientConnectionManager implements IUserLogin{
	
	private static Gson gson = new Gson(); 
	// first param(int) is the machine id
	private static Map<Integer, ConnectionInfo> connections = new HashMap<Integer, ConnectionInfo>();
	private static Logger logger = Logger.getLogger(ExceptionManager.class);
	
	
	//public volatile static Map<String, Integer> vipPoints = new HashMap<String,Integer>();
	public  static Map<String, Double> allRecharge = new HashMap<String,Double>();
	public  static Map<String, Double> allConsume = new HashMap<String,Double>();
	private GMPlayerManager GMP = null;
	
	//spring计划任务，定时清理无效的连接,每五秒一次
	@Scheduled(cron = "0/60 * * * * *")
	public void cleanUp(){
		long nowTime =0;
			Iterator<Map.Entry<Integer, ConnectionInfo>> it = connections.entrySet().iterator();
			while(it.hasNext()){
				nowTime =System.currentTimeMillis()/1000;
	            Map.Entry<Integer, ConnectionInfo> entry = it.next();  
	            if(!entry.getValue().getCtx().channel().isActive()){
					//System.out.println("remove connection of machine id: " + entry.getKey());
	            	logger.info("remove connection of machine id:"+entry.getKey());
					synchronized(connections) {
						it.remove();
					}
				}else if (nowTime-entry.getValue().getPingTime()>60) {
					logger.info("remove pingTime >60 connection of machine id :"+entry);
	            	//System.out.println("remove pingTime >60 connection of machine id :"+entry.getKey());
	            	entry.getValue().getCtx().close();
	            	MyFactory.context.getBean("DBService", DBService.class)
	        		.updateMidOnline(entry.getKey(),MachineStatus.MACHINE_NOT_ON_LINE);
	            	synchronized(connections) {
	            		it.remove();
	            	}
	            }
	        }
	}
	
	//初始化，注册observer到message center(->是java1.8的特性，lambda表达式：x -> x+1,返回x+1）
	public void init(){
		MessageCenter mc = MyFactory.context.getBean("MessageCenter", MessageCenter.class);
		mc.register(PROTOID.LOGIN_GAME_SVR_REQ, (int cmd, IRequest request)->handleMachineLogin(cmd, request));
		mc.register(PROTOID.PLAYER_LOGOUT_REQ, (int cmd, IRequest request)->handlePlayLogout(cmd, request));
		mc.register(PROTOID.MACHINE_TIME_VERIFICATION_REQ, (int cmd, IRequest request)->handleMachineTimeVerification(cmd, request));
		mc.register(PROTOID.TEST_LOGIN, (int cmd, IRequest request)->testLogin(cmd, request));
		
		GMP=MyFactory.context.getBean("GMPlayerManager", GMPlayerManager.class);
	}
	
	public int handleMachineTimeVerification(int cmd, IRequest request) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		setPingTmie(request.getMachineId());
		MachineTimeVerificationRequest req = (MachineTimeVerificationRequest) request;
		MachineTimeVerificationResponse rsp = new MachineTimeVerificationResponse();
		rsp.setMachineTime(req.getMachineTime());
		rsp.setResult(ResultTypeList.SUCCESS);
		rsp.setServerTime(System.currentTimeMillis());
		ChannelFuture cf = sendResponse(PROTOID.MACHINE_TIME_VERIFICATION_RSP, req.getMachineId(), rsp);
		if(cf == null){
			return ResultTypeList.NO_CONNECTION_FOUND;
		}
		else return rsp.getResult();
	}
	
	//处理机器连接请求
	public int handleMachineLogin(int cmd, IRequest request) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		// record the connection information
		MachineLoginRequest req = (MachineLoginRequest) request;
		MachineLoginResponse rsp = new MachineLoginResponse();
		if(req.getMachineId()==-1 ||req.getCtx()==null || "".equals(req.getPrivateIp())||req.getPrivatePort()==-1) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			sendResponse(PROTOID.LOGIN_GAME_SVR_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		ConnectionInfo connInfo = new ConnectionInfo();
		connInfo.setMachineId(req.getMachineId());
        connInfo.setCtx(req.getCtx());
        connInfo.setPrivateIp(req.getPrivateIp());
        connInfo.setPrivatePort(req.getPrivatePort());
        // get remote address and port
        if(null ==req.getCtx()) {
        	 connInfo.setPublicIp("");
             connInfo.setPublicPort(0);
        }else {
        	InetSocketAddress address = (InetSocketAddress) req.getCtx().channel().remoteAddress();
            connInfo.setPublicIp(address.getAddress().getHostAddress());
            connInfo.setPublicPort(address.getPort());
		}
        removeExistMid(req.getMachineId(),connInfo);
       
        String QrcodeUrl =MyFactory.context.getBean("QRCodeManager",QRCodeManager.class).getQRCode(req.getMachineId());
        if("".equals(QrcodeUrl)) {
        	rsp.setResult(ResultTypeList.MACHINE_NO_REGUSTER);
        	sendResponse(PROTOID.LOGIN_GAME_SVR_RSP, req.getMachineId(), rsp);
        	return ResultTypeList.MACHINE_NO_REGUSTER;
        }
        rsp.setQrcodeUrl(QrcodeUrl);    
        rsp.setResult(ResultTypeList.SUCCESS);
        rsp.setPublicIp(connInfo.getPublicIp());
        rsp.setPublicPort(connInfo.getPublicPort());
		judgeMidActivate(req.getMachineId(),rsp);
		ChannelFuture cf = sendResponse(PROTOID.LOGIN_GAME_SVR_RSP, req.getMachineId(), rsp);
		if(cf == null){
			return ResultTypeList.NO_CONNECTION_FOUND;
		}
		else return rsp.getResult();
	}
	
	private void judgeMidActivate(int machineId, MachineLoginResponse rsp) {
		String httpResult;
		try {
			URI getUri = new URIBuilder("http://"+SocketServer.adress+":30666/MachineActiveStatus/"+Integer.toString(machineId))	
					.build();
			httpResult = MyFactory.context.getBean("HttpClient", HttpClient.class).httpGet(getUri);
			if(httpResult ==null) {
				judgeActiveteByself(machineId,rsp);	
				return;		
			}
		} catch (BeansException |URISyntaxException| IOException e) {
			judgeActiveteByself(machineId, rsp);
			return;
		}
		MachineActivateInfo mInfo= gson.fromJson(httpResult, new TypeToken<MachineActivateInfo>(){}.getType()); 
		
		if(mInfo.getSTATUS() ==1) {//php那边0表示未注册，vod这边0表示成功
			rsp.setStatus(MachineStatus.NORMAL);
		}else if (mInfo.getSTATUS() ==0) {
			rsp.setStatus(MachineStatus.MACHINE_NO_ACTIVATE);	
		}else {
			rsp.setStatus(MachineStatus.NO_KOWN_STATUS);
		}
		if(mInfo.getActiveUrl() !=null) {
			rsp.setMusicpro_mid(mInfo.getActiveUrl().getMusicpro_mid());
		}
	}
	

	private void judgeActiveteByself(int machineId, MachineLoginResponse rsp) {
		boolean isActivate =MyFactory.context.getBean("DBService", DBService.class).midISActivate(machineId);
		if(isActivate) {
			rsp.setStatus(MachineStatus.NORMAL);
		}else {
			rsp.setStatus(MachineStatus.MACHINE_NO_ACTIVATE);
		}
		rsp.setMusicpro_mid(machineId);
		
	}

	//处理用户登出请求
	public int handlePlayLogout(int cmd, IRequest request) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		PlayerLogoutRequest req = (PlayerLogoutRequest) request;
		ConnectionInfo connInfo = getConnectionInfo(req.getMachineId());
		PlayerLogoutResponse rsp = new PlayerLogoutResponse();
		if(req.getMachineId() ==-1 || req.getOpenId() =="") {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			sendResponse(PROTOID.PLAYER_LOGOUT_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		//System.out.println("getLoginedOpenid-----"+connInfo.getLoginedOpenid());
		//System.out.println("req.getOpenId()--------"+req.getOpenId());
		UserInfo userInfo = new UserInfo();
		if(connInfo.getLoginedOpenid().equals(req.getOpenId())){
			connInfo.setLoginedOpenid("");
			logger.info("user: " + req.getOpenId() + " logout");
			//System.out.println("user: " + req.getOpenId() + " logout");
			//userInfo.setEndTime(0);//手动退出时间清零
			userInfo.setIsOnline(MachineStatus.PLAYER_NOT_ON_LINE);//2表示不在线
			userInfo.setWechatOpenid(req.getOpenId());
			userInfo.setLoginMachine(req.getMachineId());
			if(allRecharge.containsKey(req.getOpenId())) {
				allRecharge.remove(req.getOpenId());
			}
			if(allConsume.containsKey(req.getOpenId())) {
				allConsume.remove(req.getOpenId());
			}
			//MyFactory.context.getBean("GetPayResult", GetPayResult.class).removeMap(req.getOpenId());
			try {
				MyFactory.context.getBean("DBService", DBService.class).updateUserLogout(userInfo);
			} catch (BeansException | SQLException e) {
				//System.out.println("handlePlayLogout BeansException | SQLException:"+e);
				logger.info(e);
				rsp.setResult(ResultTypeList.UPDATA_DB_EXCEPTION);
				sendResponse(PROTOID.PLAYER_LOGOUT_RSP, req.getMachineId(), rsp);
				return ResultTypeList.UPDATA_DB_EXCEPTION;
			}
			rsp.setResult(ResultTypeList.SUCCESS);
		}
		else {
			rsp.setResult(ResultTypeList.ERROR_ARGS);
		}
		
		ChannelFuture cf = sendResponse(PROTOID.PLAYER_LOGOUT_RSP, req.getMachineId(), rsp);
		GMP.removeGM(req.getOpenId());
		if(cf == null)
			return ResultTypeList.NO_CONNECTION_FOUND;
		else {
			MyFactory.context.getBean("DBService", DBService.class)
			.updateMidOnline(req.getMachineId(),MachineStatus.MACHINE_NO_PLAYER);
			return rsp.getResult();
		}
	}
	
	//向某一已连接的主机发送消息
	public ChannelFuture sendResponse(int cmd, int machineId, Object rsp) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		MessageManager messageManager = MyFactory.context.getBean("MessageManager", MessageManager.class);
		ByteBuf buf = messageManager.generateCommandBuf(cmd, machineId, rsp);
		ConnectionInfo connInfo = this.getConnectionInfo(machineId);
		if(connInfo != null){
			while (connInfo.getCtx().channel().isActive()) {
				if(connInfo.getCtx().channel().isWritable()){
					return  connInfo.getCtx().writeAndFlush(buf);
				}
			}
			//System.out.println("sendResponse channel status not active machineId: "+machineId);
			logger.info("sendResponse channel status not active machineId: "+machineId);
			return null;
		}
		else {
			logger.info("no connection for machine " + machineId);
			//System.out.println("no connection for machine " + machineId);
			return null;
		}
		
		//return null;
	}
	
	public String getOpenIdByMachine(int machineId){
		if(connections.containsKey(machineId))
			return getConnectionInfo(machineId).getLoginedOpenid();
		return null;
	}
	
	public ConnectionInfo addConnection(int machineName, ConnectionInfo connInfo){
		MyFactory.context.getBean("DBService", DBService.class)
		.updateMidOnline(machineName,MachineStatus.MACHINE_ON_LINE);
		long pingTime = System.currentTimeMillis()/1000;
		connInfo.setPingTime(pingTime);
		synchronized (connections) {
			return connections.put(machineName, connInfo);
		}
	}
	
	public void setPingTmie(int machineName) {
		long pingTime = System.currentTimeMillis()/1000;
		if(connections.containsKey(machineName))
			connections.get(machineName).setPingTime(pingTime);
	}
	
	public ConnectionInfo removeConnection(int machineName){
		MyFactory.context.getBean("DBService", DBService.class)
		.updateMidOnline(machineName,MachineStatus.MACHINE_NOT_ON_LINE);
		synchronized (connections) {
			return connections.remove(machineName);
		}
	}
	
	public ConnectionInfo getConnectionInfo(int machineName){	
				return connections.get(machineName);						
	}
	
	public boolean removeExistMid(int machineId, ConnectionInfo connInfo) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {	
		
		if(null!=getConnectionInfo(machineId)&&machineId==getConnectionInfo(machineId).getMachineId()) {
			MachineIDLeavedNTF rsp = new MachineIDLeavedNTF();
			sendResponse(PROTOID.NTF_MACHINELEAVED, machineId, rsp);
			getConnectionInfo(machineId).getCtx().close();
			//System.out.println("closeExistMid :"+machineId);
			logger.info("closeExistMid :"+machineId);
		}
		addConnection(machineId, connInfo);
		return true;		
	}

	@Override
	public String login(int protoId, String baseInfo, String additionalInfo) throws Exception {
		long startTime = System.currentTimeMillis();
		if(protoId == PROTOID.WECHAT_LOGIN_LESTUDIO_REQ){
			ObjectMapper mapper = new ObjectMapper();
			QRCodeEvent event = mapper.readValue(baseInfo, QRCodeEvent.class);
			WeixinUserInfo wUserInfo = mapper.readValue(additionalInfo, WeixinUserInfo.class);
			//System.out.println("get user login req for: " + event.getFromUserName() + " by machine: " + event.getEventKey());
			if("".equals(event.getEventKey())) {
				//System.out.println("the user login of machine is null");
				logger.info("the user login of machine is null");
				return "";
			}
			int machineId = Integer.valueOf(event.getEventKey());
			//判断用户是否在其它机器上登录是则将其下线
			MyFactory.context.getBean("GetPayResult", GetPayResult.class).
			removeWhileOtherMid(wUserInfo.getOpenId(), machineId);
			UserInfo userInfo = getUserInfoByWUserInfo(wUserInfo,machineId);
			allRecharge.put(userInfo.getWechatOpenid(), userInfo.getAll_recharge());
			allConsume.put(userInfo.getWechatOpenid(), userInfo.getAll_consume());

			ConnectionInfo connInfo = getConnectionInfo(Integer.valueOf(event.getEventKey()));
			GameServerWechatLoginNTF ntf = new GameServerWechatLoginNTF();
			
			if(connInfo == null){
				return "fail, no connection found";
			}
			wUserInfo.setVipGrade(userInfo.getVipGrade());
			ntf.setPlayerInfo(wUserInfo);
			ntf.setUid(userInfo.getUid());
			System.out.println("uid:"+userInfo.getUid());
			int state = PlayerManager.selectPlayerState(wUserInfo.getOpenId());
			ntf.setState(state);
			//ntf.setEndTime(userInfo.getEndTime());//登录增收半个小时游戏时间
			ntf.setEndTime(System.currentTimeMillis()+60*15*1000);
			ntf.setkCoin(userInfo.getkCoin());
			//System.out.println("openid: " + connInfo.getLoginedOpenid());
			if(connInfo.getLoginedOpenid().equals("")){
				connInfo.setLoginedOpenid(event.getFromUserName());
				long sendBefor =System.currentTimeMillis();
				System.out.println("sendBefor---"+(sendBefor-startTime));
				ChannelFuture cf = sendResponse(PROTOID.GAME_SVR_PLAYER_LOGIN_NTF, machineId, ntf);
				System.out.println("sendafter---"+(System.currentTimeMillis()-startTime));
				if(ntf.getEndTime()!=0) {
					EndTimeInfo einfo= new EndTimeInfo();
					einfo.setEndTime(ntf.getEndTime());
					einfo.setMid(machineId);
					einfo.setOpenId(userInfo.getWechatOpenid());
					//剩余时间定时检测发现过时主动告诉客户端
					MyFactory.context.getBean("GetPayResult", GetPayResult.class).putMap(userInfo.getWechatOpenid(), einfo);
				    MyFactory.context.getBean("SmsDemo",SmsDemo.class);
					//登录成功短信通知管理员
				    String sms_code="SMS_139236824";
				    //String mess = String.format("{\"city\":%s, \"nickname\":%s}",userInfo.getCity(),userInfo.getNickName()) ;
				    String mess = String.format("{\"city\":\"%s\", \"nickname\":\"%s\",\"mid\":\"%d\"}",userInfo.getCity(),userInfo.getNickName(),einfo.getMid()) ;
				    System.out.println(mess);
				    if (einfo.getMid() == 52){ 
				    	SendSmsResponse response = MyFactory.context.getBean("SmsDemo",SmsDemo.class).sendSms(sms_code, mess);
				        System.out.println("短信接口返回的数据:----------------");
				        
				        System.out.println("Code=" + response.getCode());
				        System.out.println("Message=" + response.getMessage());
				        System.out.println("RequestId=" + response.getRequestId());
				        System.out.println("BizId=" + response.getBizId());
				    }
				}
				if(cf == null){
					return "fail, no connection from machine";
				}
				MyFactory.context.getBean("DBService", DBService.class)
				.updateMidOnline(machineId,MachineStatus.MACHINE_HAVA_PLAYER);
				//System.out.println("login handled, send result to " + machineId);
				logger.info("login handled, send result to " + machineId);
			}else{
				//System.out.println("already login, nothing changed");
				logger.info("already login, nothing changed");
			}
			return "success";
		} else {
			//System.out.println("unknown proto id");
			logger.info("unknown proto id");
			return "fail";
		}
	}
	
	//将WeixinUserInfo转为UserInfo
	private UserInfo getUserInfoByWUserInfo(WeixinUserInfo wuInfo, int machineId) throws BeansException, SQLException {
	//private UserInfo getUserInfoByWUserInfo(WXLOGresponse wuInfo, int machineId) {//测试用
		UserInfo userInfo = new UserInfo();
		UserInfo mysqlUserInfo = new UserInfo();
		userInfo.setWechatOpenid(wuInfo.getOpenId());
		userInfo.setCity(wuInfo.getCity());
		userInfo.setCountry(wuInfo.getCountry());
		userInfo.setHeadImgUrl(wuInfo.getHeadImgUrl());
		userInfo.setLanguage(wuInfo.getLanguage());
		userInfo.setNickName(wuInfo.getNickname());
		userInfo.setProvince(wuInfo.getProvince());
		userInfo.setSex(wuInfo.getSex());
		userInfo.setSubscribeTime(wuInfo.getSubscribeTime());
		userInfo.setLoginMachine(machineId);
		userInfo.setIsOnline(MachineStatus.PLAYER_ON_LINE);
		long  LastLoginTime =System.currentTimeMillis();
		userInfo.setLastLoginTime(LastLoginTime);
		mysqlUserInfo=MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(wuInfo.getOpenId()); 
		if(mysqlUserInfo == null) {
			userInfo.setAvatarId(wuInfo.getAvatarId());
			MyFactory.context.getBean("DBService", DBService.class).insertUserInfo(userInfo);
			int uid=MyFactory.context.getBean("DBService", DBService.class).selectUid(userInfo.getWechatOpenid());
			userInfo.setUid(uid);
			userInfo.setEndTime(System.currentTimeMillis()+60*15*1000); //首次用户赠送15分钟游戏时间
			System.out.println("首次用户赠送15分钟");
		}else {
			userInfo.setUid(mysqlUserInfo.getUid());
			//如果和上次登录的机器号不一样则将时间清0
			if(machineId!=mysqlUserInfo.getLoginMachine())
				userInfo.setEndTime(0);
			else {
				if(mysqlUserInfo.getEndTime()-System.currentTimeMillis()<0)
					userInfo.setEndTime(0);
				else 
					userInfo.setEndTime(mysqlUserInfo.getEndTime());
			}
			wuInfo.setAvatarId(mysqlUserInfo.getAvatarId());
			if(mysqlUserInfo.getGMPlayer()==1) {
				//System.out.println("THIS IS GMPLAYER");
				//logger.info("");
				GMP.addGM(mysqlUserInfo.getWechatOpenid());
			}
			userInfo.setAvatarId(mysqlUserInfo.getAvatarId());
			
			userInfo.setkCoin(mysqlUserInfo.getkCoin());
			//System.out.println("mysqlUserInfo.getVipGrade():"+mysqlUserInfo.getVipGrade());
			userInfo.setVipGrade(mysqlUserInfo.getVipGrade());
			userInfo.setAll_consume(mysqlUserInfo.getAll_consume());
			userInfo.setAll_recharge(mysqlUserInfo.getAll_recharge());
			MyFactory.context.getBean("DBService", DBService.class).updateExceptLastLoginTime(userInfo);
			System.out.println("老用户开始更新信息--------");
			MyFactory.context.getBean("DBService",DBService.class).updateUserInfo(userInfo);
			System.out.println("老用户信息更新成功--------");
		}
		
		
		return userInfo;
	}
	
	public void ntfMidActivate(String ntfString) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		if(ntfString ==null ||"".equals(ntfString)) {
			//System.out.println("php server is null");
			logger.info("php server is null");
			return ;
		}
		String[] strarray=ntfString.split("="); 
		if(strarray.length !=2) {
			logger.info("php server is error");
			//System.out.println("php server is error");
			return ;
		}
		int mid = Integer.parseInt(strarray[1]);
		if(mid >0) {
			MachineIdStatusNTF rsp = new MachineIdStatusNTF();
			rsp.setStatus(MachineStatus.NORMAL);
			sendResponse(PROTOID.NTF_MATCHING_STATUS, mid, rsp);
		}
		
	}

	public void kickPlayer(int mid) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		PlayerLogoutRequest req = new PlayerLogoutRequest();
		req.setMachineId(mid);
		req.setOpenId(getOpenIdByMachine(mid));
		handlePlayLogout(PROTOID.PLAYER_LOGOUT_REQ,req);
		
	}

	public int testLogin(int cmd, IRequest request) throws Exception {
		long startTime = System.currentTimeMillis();
		testLogin tLogin =  (testLogin)request;
		if(tLogin.getTestId()<1) {
			System.out.println("the testId <0");
			return 0;
		}
		WeixinUserInfo wUserInfo=testLoginTowUserInfo(tLogin);
		int machineId=tLogin.getMachineId();	
			//判断用户是否在其它机器上登录是则将其下线
		MyFactory.context.getBean("GetPayResult", GetPayResult.class).
		removeWhileOtherMid(wUserInfo.getOpenId(), machineId);
		UserInfo userInfo = getUserInfoByWUserInfo(wUserInfo,machineId);
		allRecharge.put(userInfo.getWechatOpenid(), userInfo.getAll_recharge());
		allConsume.put(userInfo.getWechatOpenid(), userInfo.getAll_consume());

		ConnectionInfo connInfo = getConnectionInfo(machineId);
		GameServerWechatLoginNTF ntf = new GameServerWechatLoginNTF();
			
		if(connInfo == null){
				return ResultTypeList.NO_CONNECTION_FOUND;
			}
		wUserInfo.setVipGrade(userInfo.getVipGrade());
		ntf.setPlayerInfo(wUserInfo);
			
		int state = PlayerManager.selectPlayerState(wUserInfo.getOpenId());
		ntf.setState(state);
		ntf.setEndTime(userInfo.getEndTime());
		ntf.setkCoin(userInfo.getkCoin());
			//System.out.println("openid: " + connInfo.getLoginedOpenid());
		if(connInfo.getLoginedOpenid().equals("")){
			connInfo.setLoginedOpenid(wUserInfo.getOpenId());
			long sendBefor =System.currentTimeMillis();
			System.out.println("sendBefor---"+(sendBefor-startTime));
			ChannelFuture cf = sendResponse(PROTOID.GAME_SVR_PLAYER_LOGIN_NTF, machineId, ntf);
			System.out.println("sendafter---"+(System.currentTimeMillis()-startTime));
			if(cf == null){
					return ResultTypeList.UNKNOWN_FAIL;
			}
			MyFactory.context.getBean("DBService", DBService.class)
			.updateMidOnline(machineId,MachineStatus.MACHINE_HAVA_PLAYER);
				//System.out.println("login handled, send result to " + machineId);
			logger.info("login handled, send result to " + machineId);
		}else{
				//System.out.println("already login, nothing changed");
			logger.info("already login, nothing changed");
		}
		return ResultTypeList.SUCCESS;
	}

	private WeixinUserInfo testLoginTowUserInfo(testLogin tLogin) {
		UserInfo UserInfo =MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId("test"+tLogin.getTestId());
		WeixinUserInfo wInfo = new WeixinUserInfo();
		if(UserInfo==null) {
			wInfo.setAvatarId(101);
			wInfo.setCity("上海");
			wInfo.setCountry("中国");
			wInfo.setHeadImgUrl("http://thirdwx.qlogo.cn/mmopen/ajNVdqHZLLCeFUBJetoU8Cx7TiaYECatmuUT3xrRhIicc1C1898NDVcVhpG59SjYwwhrhyXViafzeibgj4VDKibegZkibiafU8U");
			wInfo.setLanguage("zh_CN");
			wInfo.setNickname("test"+tLogin.getTestId());
			wInfo.setOpenId("test"+tLogin.getTestId());
			wInfo.setProvince("上海");
			wInfo.setSex(1);
		}else {
			wInfo.setAvatarId(UserInfo.getAvatarId());
			wInfo.setCity(UserInfo.getCity());
			wInfo.setCountry(UserInfo.getCountry());
			wInfo.setHeadImgUrl(UserInfo.getHeadImgUrl());
			wInfo.setLanguage(UserInfo.getLanguage());
			wInfo.setNickname(UserInfo.getNickName());
			wInfo.setOpenId(UserInfo.getWechatOpenid());
			wInfo.setProvince(UserInfo.getProvince());
			wInfo.setSex(UserInfo.getSex());
		}
		return wInfo;
	}
	
	public int getMachineIdByOpenId(String openId) {
		int machineId=-1;
		for(Integer mid:connections.keySet()) {
			if(connections.get(mid).getLoginedOpenid().equals(openId)) {
				machineId=mid;
				return machineId;
			}
		}
		return machineId;
	}
	
	
}
